package com.itlong.cloud.controller.sdkV1.old.serverClient;

import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.DTO.property.PropertyEquipGetDTO;
import com.itlong.cloud.POJO.DTO.sdk.SDKDynamicPwdGetDTO;
import com.itlong.cloud.POJO.PO.AppUserInfoPO;
import com.itlong.cloud.POJO.PO.DeviceElevatorAuthPO;
import com.itlong.cloud.POJO.PO.PropertyRoleProjectPO;
import com.itlong.cloud.POJO.VO.property.AppUserGetDeviceAuthVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.common.network.tcp.mina.IMinaServiceClient;
import com.itlong.cloud.enumerate.PropertyEquipTypeEnum;
import com.itlong.cloud.enumerate.PropertyPublicRoleEnum;
import com.itlong.cloud.enumerate.oldapp.Code;
import com.itlong.cloud.enumerate.oldapp.Message;
import com.itlong.cloud.equip.property.IPropertyDeviceAuthServiceClient;
import com.itlong.cloud.equip.sdk.ISDKAppOldEquipServiceClient;
import com.itlong.cloud.equip.sdk.ISDKServerOldEquipServiceClient;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.user.sdk.ISDKAppOldUserServiceClient;
import com.itlong.cloud.user.sdk.ISDKServerOldUserServiceClient;
import com.itlong.cloud.utils.encrypt.DesEncryptUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/**
 * <desc>
 *      SDK服务端扩展功能Controller
 * </desc>
 *
 * @createDate 2017/10/26
 */
@RestController
@RequestMapping("/jiabanjing/interface")
public class SDKServerOldExtraController {

    private static Logger LOG = LoggerFactory.getLogger(SDKServerOldExtraController.class);

    @Autowired
    ISDKServerOldUserServiceClient iSDKUserServiceClient;

    @Autowired
    ISDKAppOldUserServiceClient isdkAppOldUserServiceClient; //旧版APP_SDK用户服务暴露层接口

    @Autowired
    ISDKAppOldEquipServiceClient isdkAppOldEquipServiceClient; //旧版APP_SDK设备服务层暴露接口

    @Autowired
    ISDKServerOldEquipServiceClient iSDKServerEquipServiceClient;

    @Autowired
    IPropertyDeviceAuthServiceClient iPropertyDeviceAuthServiceClient;

    @Autowired
    IMinaServiceClient iMinaServiceClient;

    /**
     * <desc>
     *      SDK接收动态密码数据并上传给一卡通用户
     * <desc/>
     * @param   appid   应用接入凭证
     * @param   sdkDynamicPwdGetDTO   动态密码接收对象
     * @return  Message   老版标准格式化响应结果
     * @author Biao.R
     * @createDate 2017/11/23
     */
    @ResponseBody
    @RequestMapping("/app/deviceOperate/getDynamicPwd")
    public Message getDynamicPwd(String appid, SDKDynamicPwdGetDTO sdkDynamicPwdGetDTO) {
        try {
            String projectId = sdkDynamicPwdGetDTO.getProjectId();
            //该功能属于服务端功能，但在app端也有集成在Demo中，二者所传的project是不一样的（服务端projectId加密）
            //if (!"app".equals(sdkDynamicPwdGetDTO.getEnvFlag())) {
            projectId = DesEncryptUtil.projectIdDesEncrypt(projectId);
            //}


            String dynamicPwd = sdkDynamicPwdGetDTO.getDynamicPwd();
            String userPhone = sdkDynamicPwdGetDTO.getUserPhone();
            String buildNum = sdkDynamicPwdGetDTO.getBuildNum();
            String unitNum = sdkDynamicPwdGetDTO.getUnitNum();
            String effectData = sdkDynamicPwdGetDTO.getEffectData();
            if (StringUtils.isEmpty(projectId)) {
                return new Message(Code.APP_DEVELOP_ERR);
            }
            //校验开发者账号是否有该项目的权限
            Message message = checkServerSDKofProject(appid, projectId);
            if (message != null) {
                return message;
            }

            if (StringUtils.isNotEmpty(dynamicPwd) && !dynamicPwd.matches("\\d{4,6}")) {
                return new Message(Code.PARAM_ERR, "动态密码长度在4~6位之间");
            }

            if (StringUtils.isEmpty(userPhone) && !userPhone.matches(PlatformConstants.USER_PHONENUM_REGIX)) {
                return new Message(Code.PARAM_ERR, "userPhone为空或格式不正确：" + userPhone);
            }

            AppUserInfoPO appUserInfoPO = iSDKUserServiceClient.getAppUserByPhone(userPhone);
            if (appUserInfoPO == null) {
                return new Message(Code.NOT_FOUNDUSER);
            }
            String userId = appUserInfoPO.getUserId();

            //第一步获取软卡号
            String cardNum = isdkAppOldUserServiceClient.getUserCardNo(userId, projectId);

            //第二步 获取服务与指定地址下（楼栋（1）、单元（n））的所有设备列表
            List<PropertyEquipGetDTO> elevatorInfoVOS = iSDKServerEquipServiceClient.getElevatorByAddress(projectId,buildNum,unitNum);

            if (elevatorInfoVOS == null || elevatorInfoVOS.isEmpty()) {
                return new Message(Code.NOT_PARAM, "请检查该地址内是否有电梯设备");
            }

            //查询用户在该项目中拥有的电梯权限
            List<AppUserGetDeviceAuthVO> userDeviceAuth = iPropertyDeviceAuthServiceClient.getUserDeviceAuth(userId, projectId, PropertyEquipTypeEnum.ELEVATOR.getType().toString());
            if (userDeviceAuth == null || userDeviceAuth.isEmpty()) {
                return new Message(Code.NOT_PARAM, "请检查该用户是否在该地址内有电梯权限");
            }

            //对地址上的电梯和人权限上的电梯求交集,获取该地址内用户拥有的设备权限
            List<Map<String, String>> userDevices = new ArrayList<>();
            List<Map<String, String>> deviceInfoList = new ArrayList<>();
            List<Integer> deviceIdList = new ArrayList<>();
            for (PropertyEquipGetDTO elevatorInfoVO : elevatorInfoVOS) {
                for (AppUserGetDeviceAuthVO appUserGetDeviceAuthVO : userDeviceAuth) {
                    String deviceUnique = appUserGetDeviceAuthVO.getDeviceUnique();
                    if (elevatorInfoVO.getDeviceUnique().equals(deviceUnique)) {
                        Map<String, String> map = new HashMap<>();
                        map.put("deviceUnique", deviceUnique);
                        map.put("floorAuth", StringHandlerUtil.getAuthCodeBynNturalFloors(appUserGetDeviceAuthVO.getNaturalFloor()));
                        // 向数据库中存储动态密码
                        userDevices.add(map);
                        //根据deviceUnique查询设备名称，返回给用户
                        Map<String, String> elevatorInfoMap = new HashMap<>();
                        elevatorInfoMap.put("deviceName", elevatorInfoVO.getDeviceName());
                        elevatorInfoMap.put("dynamicPwd", dynamicPwd);
                        deviceInfoList.add(elevatorInfoMap);
                        deviceIdList.add(Integer.parseInt(deviceUnique.substring(deviceUnique.length() - 4, deviceUnique.length())));
                    }
                }
            }
            if (userDevices == null || userDevices.isEmpty()) {
                return new Message(Code.NOT_PARAM, "请检查该用户是否在该地址内有电梯权限");
            }

            //保存动态密码信息到电梯权限表
            if (!deviceIdList.isEmpty()) {
                StringBuffer sb = new StringBuffer(PlatformConstants.MAX_ELEVATOR_DEVICEID);
                for (int i = 1; i <= PlatformConstants.MAX_ELEVATOR_DEVICEID; i++) {
                    //没有设置动态密码的设备，用FFFFFF替代
                    sb.append(deviceIdList.contains(i) ? dynamicPwd : "FFFFFF").append(",");
                }
                DeviceElevatorAuthPO elevatorAuthPO = new DeviceElevatorAuthPO(userId, projectId, sb.substring(0, sb.length() - 1).toString());
                iSDKServerEquipServiceClient.updateDynamicPwd(elevatorAuthPO);
            }

            //组装发送给一卡通的Json数据
            JSONObject cmdDataJ = new JSONObject();
            cmdDataJ.put("cardNo", cardNum);
            cmdDataJ.put("totalNumber", userDevices.size());
            cmdDataJ.put("dynamicPwd", this.desPswd(dynamicPwd));
            cmdDataJ.put("effectData", effectData.replaceAll("\\s|\n", ""));
            cmdDataJ.put("deviceList", userDevices);
            //发送给一卡通的Json数据
            JSONObject smartCardJson = new JSONObject();
            smartCardJson.put("projectId", projectId);
            smartCardJson.put("cmdType", 2);
            smartCardJson.put("cmdData", cmdDataJ);
            Code sendMessage = iMinaServiceClient.oldSendMessage(projectId, smartCardJson.toString());
            //AppErrorCodeEnum sendMessage = iMinaServiceClient.sendMessage(projectId, smartCardJson.toString());

            //组装给客户的设备信息数据
            JSONObject json2Customer = new JSONObject();
            json2Customer.put("deviceNum", deviceInfoList.size());
            json2Customer.put("deviceInfo", deviceInfoList);
            return new Message(Code.SUCCESS, json2Customer);
        } catch (Exception e) {
            throw new DataAccessException("【SDK_服务端_综合服务】接收处理动态密码异常", e);
        }
    }


    /**
     * <desc>
     *      校验开发者账号是否有该项目的权限
     * <desc/>
     * @param   appid     应用接入凭证
     * @param    projectId     独立开发者所管辖的项目Id
     * @return  Message   老版标准格式化响应结果
     * @author Biao.R
     * @createDate 2017/11/6
     */
    private Message checkServerSDKofProject(String appid, String projectId) {
        PropertyRoleProjectPO roleProjectPO = new PropertyRoleProjectPO(projectId, PropertyPublicRoleEnum.DEVELOPER.getRoleId(), appid);
        List<PropertyRoleProjectPO> roleProjectPOS = iSDKUserServiceClient.getRoleProject(roleProjectPO);
        if (roleProjectPOS != null && roleProjectPOS.isEmpty()) {
            return new Message(Code.NOT_PERMISSION);
        }
        return null;
    }


    /**
     * <desc>
     *      加密传输给一卡通的动态密码
     * <desc/>
     * @param   password   要加密的数据
     * @return  加密后的密码
     * @author Biao.R
     * @createDate 2017/11/23
     */
    public String desPswd(String password){
        Random random = new Random();
        int pswdDesCode = random.nextInt(16);
        char[] pwsddArr = password.toCharArray();
        String desPswd = "";
        for (char c : pwsddArr) {
            int i = ((int) c)^pswdDesCode ;
            desPswd += Integer.toHexString(i);
        }
        return  (desPswd+Integer.toHexString(pswdDesCode)).toUpperCase();
    }
}